/**
 * Copyright(c) 2013 Jade Techonologies Co., Ltd.
 *
 * History:
 *   13-4-14 下午11:24 Created by dwzhang
 */
package com.jade.framework.base.pattern.pipeline;

import java.util.ArrayList;
import java.util.List;

/**
 * 简单的Pipeline实现.
 *
 * @author dwzhang
 * @version 1.0 13-4-14 下午11:24
 */
public class Pipeline<Context, E extends Exception>
{
    private List<Valve<Context, E>> valves;
    private Valve<Context, E> finalValve;

    public Pipeline(int initSize)
    {
        valves = new ArrayList<Valve<Context, E>>(initSize);
    }

    public Pipeline()
    {
        this(2);
    }

    /**
     * 增加阀门
     *
     * @param valve 阀门
     */
    public void addValve(Valve<Context, E> valve)
    {
        valves.add(valve);
    }

    /**
     * 删除任务阀门
     *
     * @param valve 任务阀门
     */
    public void removeValve(Valve<Context, E> valve)
    {
        valves.remove(valve);
    }

    /**
     * 返回所有阀门
     *
     * @return 管道中的阀门
     */
    public List<Valve<Context, E>> getValves()
    {
        return valves;
    }

    public void setValves(List<Valve<Context, E>> valves)
    {
        this.valves = valves;
    }

    public Valve<Context, E> getFinalValve()
    {
        return finalValve;
    }

    public void setFinalValve(Valve<Context, E> finalValve)
    {
        this.finalValve = finalValve;
    }

    /**
     * 管道处理。
     *
     * @param context 阀门上下文
     * @throws E 处理异常.
     */
    public void handle(Context context)
            throws E
    {
        ValveChain<Context, E> chain = new SimpleValveChain<Context, E>(getValves());
        try {
            chain.handleNext(context);
        }
        finally {
            Valve<Context, E> v = getFinalValve();
            if (v != null) {
                try {
                    //final vavle的执行不能够使用chain
                    v.handle(context, null);
                }
                catch (Throwable t) {
                    //do nothing
                }
            }
        }
    }
}
